﻿using System;
using System.Collections.Generic;
using UnityEngine;

namespace YummyGame.Framework
{
    public abstract class SkillOwner : MonoBehaviour
    {
        private Dictionary<string, Skill> m_skills;

        public GameObject go => this.gameObject;
        public OwnerBaseInfo BaseInfo;
        private SkillDescriptor descriptor;
        public Dictionary<string, float> m_variables;
        private HashSet<string> m_createPath;
        public void OnVariableChanged(string key, float value)
        {

        }

        public void Initialize(string path)
        {
            descriptor = new SkillDescriptor(path);
            Create(descriptor);
        }

        private void Create(SkillDescriptor desc)
        {
            if (m_createPath.Contains(desc.fullPath)) return;
            m_createPath.Add(descriptor.fullPath);
            if (desc.extends != null) Create(desc.extends);
            CreateBaseInfo(desc);
        }

        private void CreateBaseInfo(SkillDescriptor desc)
        {
            SkillKeyValuePair kv = desc.GetBaseInfo();
            if (kv == null) return;
            foreach (var root in kv.field.pairs)
            {
                string rootName = root.key;
                string typeName = "YummyGame.Framework.OwnerInfoBuilder_" + rootName;
                Type type = Type.GetType(typeName);
                if (type == null) continue;
                OwnerInfoBuilder build = (OwnerInfoBuilder)Activator.CreateInstance(type);
                build.Build(BaseInfo, root.field);
            }
        }

        private void CreateVariable(SkillDescriptor desc)
        {
            SkillKeyValuePair kv = desc.GetVariable();
            if (kv == null) return;
            foreach (var variable in kv.field.pairs)
            {
                if (!variable.field.IsNumber()) continue;
                DefineVariable(variable.key, variable.field.AsNumber());
            }
        }


        protected virtual void Awake()
        {
            m_variables = new Dictionary<string, float>();
            m_skills = new Dictionary<string, Skill>();
            m_createPath = new HashSet<string>();
        }

        protected virtual void Update()
        {
            foreach (var kv in m_skills)
            {
                kv.Value.Tick();
            }
        }

        protected virtual void OnDestroy()
        {

        }

        public void LoadSkillFromJson(string path)
        {
            SkillPrototype protoType = SkillPrototypeLib.GetPrototype(path);
            Skill skill = protoType.GetSkill(this);

            m_skills.Add(path, skill);
        }

        public bool CanUseSkill(string name)
        {
            Skill s = GetSkill(name);
            return s != null && s.CanUse();
        }

        public void UseSkill(string name)
        {
            if (!HasSkill(name)) return;
            Skill s = GetSkill(name);
            s.Use();
        }

        public bool HasSkill(string name)
        {
            return m_skills.ContainsKey(name);
        }


        public void DefineVariable(string key,float value)
        {
            if (HasVariable(key)) throw new Exception("变量名重复");
            m_variables[key] = value;
        }

        public bool HasVariable(string key)
        {
            return m_variables.ContainsKey(key);
        }

        public float GetVariable(string name, string key)
        {
            return m_variables[name];
        }

        public bool SetVariable(string key, float value)
        {
            m_variables[key] = value;
            return true;
        }

        public Skill GetSkill(string name)
        {
            Skill s = null;
            if (m_skills.TryGetValue(name, out s)) return s;
            return null;
        }
    }
}
